import json
import shlex
import math
import urllib.parse
from datetime import datetime

INDENT = 4  # 缩进量
PRINTLINE = 80  # 每行最大字符数


def get_request_type(headers, data):
    """
    根据请求头和数据格式判断是 params、data 还是 json
    :param headers: 请求头字典
    :param data: 请求体字符串
    :return: 'params', 'data' 或 'json'
    """
    content_type = headers.get('Content-Type', '').lower()

    # 如果是 JSON 格式
    if content_type == 'application/json':
        return 'json'

    # 如果是表单数据格式
    if content_type == 'application/x-www-form-urlencoded':
        return 'data'

    # 如果没有 Content-Type，尝试解析数据
    try:
        parsed_data = json.loads(data)  # 如果能解析为 JSON
        return 'json'
    except (json.JSONDecodeError, TypeError):
        pass

    # 如果是 key=value 形式
    if '=' in data and '&' in data:
        return 'data'

    return 'params'  # 默认使用 params


def convert_value(value):
    """
    转换字段值：如果遇到时间或异常值，进行处理。
    :param value: 需要转换的值
    :return: 转换后的值
    """
    # 如果值是时间字符串，尝试转换为标准格式
    try:
        if isinstance(value, str):
            # 尝试检测并转换日期格式
            date_formats = ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%d/%m/%Y']
            for date_format in date_formats:
                try:
                    return datetime.strptime(value, date_format).isoformat()
                except ValueError:
                    continue
    except Exception as e:
        print(f"转换值时出错: {e}")

    # 默认返回原始值
    return value


def print_key_val(key_prefix, value, pre_indent=0, end=','):
    """
    打印字典的键值对，并插入到代码列表中。
    :param key_prefix: 键的初始化字符串，例如 "'key': " 或 "url = "
    :param value: 值
    :param pre_indent: 缩进层级，默认值为0
    :param end: 行尾符号，默认为逗号
    :return: 格式化的代码行
    """
    value = convert_value(value)  # 转换字段值
    indent = INDENT * pre_indent
    start = indent + len(key_prefix)
    left = PRINTLINE - start - 4  # 计算每行字符数限制
    formatted_code_lines = []

    # 处理短值，直接添加到代码行
    formatted_code_lines.append(f"{' ' * indent}{key_prefix}'{value[:left]}'")

    if len(value) > left:
        formatted_code_lines[-1] += " \\"  # 内容太长时继续到下一行
        line_count = math.ceil(len(value) / left)
        for i in range(1, line_count):
            delim = " \\"  # 继续换行
            if i == line_count - 1:
                delim = end
            formatted_code_lines.append(f"{' ' * start}'{value[i * left:(i + 1) * left]}{delim}")
    else:
        formatted_code_lines[-1] += end
    return formatted_code_lines


def dict_to_code(name, simple_dict):
    """
    将字典转换为Python兼容的键值对代码。
    :param name: 变量名
    :param simple_dict: 需要转换的字典
    :return: 转换后的Python代码
    """
    formatted_code_lines = []
    if simple_dict:
        formatted_code_lines.append(f"{name} = {{")
        for k, v in simple_dict.items():
            key_prefix = f"'{k}': "
            formatted_code_lines += print_key_val(key_prefix, v, 1)
        formatted_code_lines.append("}\n")
    return formatted_code_lines


def curl_to_requst(command):
    """
    将curl命令转换为Python脚本
    :param command: curl命令
    :return: 转换后的Python代码
    """
    command_args = shlex.split(command)
    data = None

    # 解析请求方法
    method = 'get'  # 默认方法为 GET
    if '-X' in command_args:
        method = command_args[command_args.index('-X') + 1]
    elif '--data' in command_args or '--data-raw' in command_args:
        method = 'post'
        data = command_args[command_args.index('--data') + 1] if '--data' in command_args else command_args[command_args.index('--data-raw') + 1]

    url = command_args[1]

    # 解析header
    headers = {}
    for i, v in enumerate(command_args):
        if '-H' in v:
            header_parts = command_args[i + 1].split(':', 1)
            if len(header_parts) == 2:  # 确保header是正确格式
                headers[header_parts[0].strip()] = header_parts[1].strip()

    # 解析cookies
    cookies = {}
    if 'Cookie' in headers or 'cookie' in headers:
        cookie_header = 'Cookie' if 'Cookie' in headers else 'cookie'
        cookie = headers.pop(cookie_header)
        cookies = dict([c.strip().split('=', 1) for c in cookie.split(';')])

    # 对data进行URL解码
    if data:
        data = urllib.parse.unquote(data)

    # 如果data为空，则从URL中提取参数
    if not data:
        parsed_url = urllib.parse.urlparse(url)
        query_params = urllib.parse.parse_qs(parsed_url.query)
        if query_params:
            data = '&'.join([f"{k}={v[0]}" for k, v in query_params.items()])

    # 转换data为字典格式
    data_dict = {}
    if data:
        data_dict = dict([item.split('=') for item in data.split('&')])

    pk = get_request_type(headers, data)
    return url, pk, headers, method, data_dict, cookies

def main():
    curl_command = """
    curl 'https://test.lirenos.com/api/v2/rankings/totalList?recStart=1&pageSize=10&addTimeNum=1&startTime=2025-03-01+00:00:00&endTime=2025-03-27+23:59:59&nameOrPhone=&startTotalCheck=&endTotalCheck=&startAttendance=&endAttendance=&startSelf=&endSelf=&startLeague=&endLeague=&startPrivate=&endPrivate=&startVenue=&endVenue=&startTicket=&endTicket=&storeId=1&companyId=1&token=usertoken%40f06ba7da-3b00-4dda-b97d-d3370f086606&randomServerTime=1743060677866' \
    -H 'Accept: application/json, text/plain, */*' \
    -H 'Accept-Language: zh,zh-CN;q=0.9,en;q=0.8' \
    -H 'Cache-Control: no-cache' \
    -H 'Connection: keep-alive' \
    -b 'goeasyNode=6' \
    -H 'Origin: https://testbeta.lirenos.com' \
    -H 'Pragma: no-cache' \
    -H 'Referer: https://testbeta.lirenos.com/' \
    -H 'Sec-Fetch-Dest: empty' \
    -H 'Sec-Fetch-Mode: cors' \
    -H 'Sec-Fetch-Site: same-site' \
    -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36' \
    -H 'sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"' \
    -H 'sec-ch-ua-mobile: ?0' \
    -H 'sec-ch-ua-platform: "Windows"'
    """
    url, pk, headers, method, data_dict, cookies = curl_to_requst(curl_command)

    print("\n最终提取结果：")
    print("URL:", url)
    print("pk:", pk)
    print("Headers:", headers)
    print("method:", method)
    print("data:", data_dict)
    print("Cookies:", cookies)

if __name__ == "__main__":
    main()
